Skip to content

docs: correct schema reference against the live database - #530

Merged
guillermoscript merged 1 commit into
masterfrom
docs/schema-doc-accuracy-audit
Jul 25, 2026
Merged

docs: correct schema reference against the live database#530
guillermoscript merged 1 commit into
masterfrom
docs/schema-doc-accuracy-audit

Conversation

@guillermoscript

Copy link
Copy Markdown
Owner

Follow-up to #529. Verified the schema docs table-by-table against the live database instead of trusting the prose.

Types: no change needed

lib/database.types.ts is in sync. Regenerating from the local DB produces a byte-identical file except the __InternalSupabase header that --linked adds:

npx supabase gen types typescript --local --schema public > /tmp/types.ts
diff /tmp/types.ts lib/database.types.ts
# only the __InternalSupabase PostgrestVersion block

So local migrations, cloud schema, and the committed types all agree.

The schema doc did not

Each of these silently breaks a query or an .rpc() call:

Documented Actually
enrollments.product_id / subscription_id + CHECK Dropped by the entitlements migration. entitlements — the source of truth for access — was missing from the doc entirely
plans.name, .interval, .stripe_*_id plan_name, duration_in_days, provider_*_id
subscriptions.status, .stripe_subscription_id, .created_at subscription_status, provider_subscription_id, created
exercise_completions.student_id + submission/is_correct/ai_feedback user_id + completed_by/score
exercises.initial_code / solution_code / test_cases None exist
products.stripe_product_id / stripe_price_id provider_product_id / provider_price_id
exam_questions.sequence Does not exist
exam_submissions.is_reviewed review_status
12 gamification tables incl. gamification_daily_caps, gamification_challenges 10 — those two do not exist
One composite unique index on transactions Three (product-shaped, plan-shaped, provider_charge_id idempotency)
currency_type = usd, eur Eight values
handle_new_subscription(3 args), save_exam_feedback(6 args), award_xp(p_user_id, p_action_type, p_reference_id) 4, 9 (p_-prefixed), and award_xp(_user_id, _action_type, _xp_amount, _reference_id, _reference_type)
"65+ tables" 116

Making it self-correcting

The doc drifted because there was no cheap way to check it. Added:

  • § Verifying this document — the one-line diff and psql introspection commands for columns, enums and exact RPC signatures, plus the source-of-truth ordering (generated types → live DB → this page).
  • § Tables without tenant_id — the full 55-table list and the query that regenerates it. Filtering one of these by tenant_id errors the entire query; it's a recurring cause of blank pages.

Two more traps for new devs

  • docs/README.md indexed six files that don't exist (API_ROUTES.md, RLS_POLICIES.md, four features/*.md) and advertised the project as "Phase 5 complete, Phase 6 next". Rewritten as a real map, with a note on which parts of docs/ are historical records rather than references.
  • docs/ACTUAL_SCHEMA.md claims to be "the actual column names from the live database" and is what a name-search surfaces first — but it's a Feb 2026 snapshot still documenting the dropped enrollments columns. Now carries a stale banner pointing at the real sources.

CLAUDE.md also had the wrong RPC signatures, a four-file E2E test list where 33 specs now live, and creator@codeacademy.com labelled teacher when the seed makes it admin.

Test plan

Docs only.

  • Every claim changed here checked against the live DB (information_schema, pg_indexes, pg_constraint, pg_enum, pg_get_function_identity_arguments).
  • lib/database.types.ts diffed against freshly generated local types.
  • All relative links in the touched docs resolve.

🤖 Generated with Claude Code

https://claude.ai/code/session_01853LDokPbhv9Kg9Ctz9DB5

Verified docs/DATABASE_SCHEMA.md table by table against the local
database (which matches cloud — see below) and fixed what was wrong.

lib/database.types.ts needed no change: regenerating it from the local
DB produces a byte-identical file apart from the __InternalSupabase
header that `--linked` adds. Local migrations, cloud schema and the
committed types are all in sync.

Columns that did not exist as documented (each one silently breaks a
query or a .rpc() call):

- enrollments: still listed product_id/subscription_id and their CHECK
  constraint, all dropped by the entitlements migration. entitlements
  itself was absent from the doc entirely despite being the source of
  truth for course access.
- plans: documented `name`, `interval`, `stripe_*_id`; actually
  plan_name, duration_in_days, provider_*_id.
- subscriptions: documented `status`, `stripe_subscription_id`,
  `created_at`; actually subscription_status, provider_subscription_id,
  created.
- exercise_completions: documented student_id + submission/is_correct/
  ai_feedback; actually user_id + completed_by/score.
- exercises: documented initial_code/solution_code/test_cases — none
  exist.
- products: documented stripe_product_id/stripe_price_id; actually
  provider_*_id.
- exam_questions: documented a `sequence` column that does not exist.
- exam_submissions: documented is_reviewed; actually review_status.
- gamification: documented 12 tables including gamification_daily_caps
  and gamification_challenges, neither of which exists. There are 10.
- transactions: documented one composite unique index; there are three
  (product-shaped, plan-shaped, provider_charge_id idempotency).
- currency_type: documented usd/eur; there are eight values.
- RPCs: handle_new_subscription is missing _start_date,
  save_exam_feedback takes nine p_-prefixed args not six, award_xp's
  signature was wrong in CLAUDE.md and AI_AGENT_GUIDE.md.
- Table count was "65+" everywhere; it is 116.

Also adds what the doc had no way to keep right on its own:

- "Verifying this document" — the diff/introspection commands to check
  any claim here against the database in one line.
- "Tables without tenant_id" — the full 55-table list plus the query
  that regenerates it. Filtering these by tenant_id errors the whole
  query, which is a recurring source of blank pages.
- docs/README.md rewritten: it indexed six files that do not exist
  (API_ROUTES.md, RLS_POLICIES.md, four features/*.md) and advertised
  the project as "Phase 5 complete, Phase 6 next".
- docs/ACTUAL_SCHEMA.md now carries a stale banner — it claims to be
  the actual live schema and is the first thing a name-search finds,
  but it is a February 2026 snapshot documenting dropped columns.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01853LDokPbhv9Kg9Ctz9DB5
@guillermoscript
guillermoscript merged commit 52ab5e9 into master Jul 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant